%% Copyright
-module(riak_catalog).
-author("").

-define(product_bucket, <<"products">>).
-define(review_bucket, <<"reviews">>).

%% API
-export([add_product/2,
         get_product/2,
         add_product_review/3,
         get_product_review/3,
         update_product_review/4]).

-export([init/1]).

init({Address, Port}) ->
  {ok, Pid} = riakc_pb_socket:start_link(Address, Port),
  {ok, Pid}.

add_product(Pid, Product) ->
  ProductObject = riakc_obj:new(?product_bucket, undefined, Product),
  {ok, Object} = riakc_pb_socket:put(Pid, ProductObject),
  {ok, riakc_obj:key(Object)}.

get_product(Pid, ProductId) ->
  case riakc_pb_socket:get(Pid, ?product_bucket, ProductId) of
    {ok, ProductObject} ->
      {ok, riakc_obj:get_value(ProductObject)};
    _ ->
      {error, not_found}
  end.

add_product_review(Pid, ProductId, Review) ->
  {ok, ProductObject} = riakc_pb_socket:get(Pid, ?product_bucket, ProductId),

  ReviewObject = riakc_obj:new(?review_bucket, undefined, Review),
  {ok, PersistedReview} = riakc_pb_socket:put(Pid, ReviewObject),

  Metadata = riakc_obj:get_update_metadata(ProductObject),
  MetadataWithLinks = riakc_obj:add_link(Metadata, [{<<"review">>, [{<<"review">>, riakc_obj:key(PersistedReview)}]}]),

  UpdatedProductObject = riakc_obj:update_metadata(ProductObject, MetadataWithLinks),
  riakc_pb_socket:put(Pid, UpdatedProductObject),

  {ok, riakc_obj:key(PersistedReview)}.

update_product_review(Pid, ProductId, ReviewId, ReviewUpdate) ->
  {ok, _ProductObject} = riakc_pb_socket:get(Pid, ?product_bucket, ProductId),
  {ok, ReviewObject} = riakc_pb_socket:get(Pid, ?review_bucket, ReviewId),

  riakc_obj:update_value(ReviewObject, ReviewUpdate),
  {ok, _UpdatedReview} = riakc_pb_socket:put(Pid, ReviewObject),

  {ok, riakc_obj:key(ReviewObject)}.

get_product_review(Pid, ProductId, ReviewId) ->
  {ok, _ProductObject} = riakc_pb_socket:get(Pid, ?product_bucket, ProductId),
  {ok, ReviewObject} = riakc_pb_socket:get(Pid, ?review_bucket, ReviewId),

  {ok, jsx:decode(riakc_obj:get_value(ReviewObject))}.